﻿using DDCMS.Domain.Interface;
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Threading.Tasks;

namespace DDCMS.EntityFrameworkCore
{
    public class UnitWork:IUnitWork
    {
        private CMSContext _context;
        public UnitWork(CMSContext context)
        {
            _context = context;
        }

        /// <summary>
        /// 根据过滤条件，获取记录
        /// </summary>
        /// <param name="exp">The exp.</param>
        public IQueryable<T> Find<T>(Expression<Func<T, bool>> exp = null) where T:class
        {
            return Filter(exp);
        }

        public bool IsExist<T>(Expression<Func<T, bool>> exp) where T:class
        {
            return _context.Set<T>().Any(exp);
        }

        /// <summary>
        /// 查找单个
        /// </summary>
        public T FindSingle<T>(Expression<Func<T, bool>> exp) where T:class
        {
            return _context.Set<T>().AsNoTracking().FirstOrDefault(exp);
        }

        /// <summary>
        /// 得到分页记录
        /// </summary>
        /// <param name="pageindex">The pageindex.</param>
        /// <param name="pagesize">The pagesize.</param>
        /// <param name="orderby">排序，格式如："Id"/"Id descending"</param>
        public IQueryable<T> Find<T>(int pageindex, int pagesize, Expression<Func<T, int>> orderby = null, Expression<Func<T, bool>> exp = null) where T:class
        {
            if (pageindex < 1) pageindex = 1;
            
            return Filter(exp).OrderBy(orderby).Skip(pagesize * (pageindex - 1)).Take(pagesize);
        }

        /// <summary>
        /// 根据过滤条件获取记录数
        /// </summary>
        public int GetCount<T>(Expression<Func<T, bool>> exp = null) where T:class
        {
            return Filter(exp).Count();
        }

        public void Add<T>(T entity) where T:class
        {
            _context.Set<T>().Add(entity);
            Save();
        }
        public T Insert<T>(T entity) where T:class
        {
            _context.Set<T>().Add(entity);
            _context.SaveChanges();
            return entity;
        }

        /// <summary>
        /// 批量添加
        /// </summary>
        /// <param name="entities">The entities.</param>
        public void BatchAdd<T>(T[] entities) where T:class
        {

            _context.Set<T>().AddRange(entities);
            Save();
        }

        public void Update<T>(T entity) where T:class
        {
            var entry = this._context.Entry(entity);
            //todo:如果状态没有任何更改，会报错
            entry.State = EntityState.Modified;

            Save();
        }

        public void Delete<T>(T entity) where T:class
        {
            _context.Set<T>().Remove(entity);
            Save();
        }

        /// <summary>
        /// 按指定id更新实体,会更新整个实体
        /// </summary>
        /// <param name="identityExp">The identity exp.</param>
        /// <param name="entity">The entity.</param>
        public void Update<T>(Expression<Func<T, object>> identityExp, T entity) where T:class
        {
            _context.Set<T>().Update(entity);
            Save();
        }

        /// <summary>
        /// 实现按需要只更新部分更新
        /// <para>如：Update(u =>u.Id==1,u =>new User{Name="ok"});</para>
        /// </summary>
        /// <param name="where">The where.</param>
        /// <param name="entity">The entity.</param>
        public void Update<T>(Expression<Func<T, bool>> where, Expression<Func<T, T>> entity) where T:class
        {
            _context.Set<T>().Where(where);
        }

        public virtual void Delete<T>(Expression<Func<T, bool>> exp) where T:class
        {
            _context.Set<T>().Where(exp);
        }

        public void Save()
        {
            _context.SaveChanges();
        }

        private IQueryable<T> Filter<T>(Expression<Func<T, bool>> exp) where T:class
        {
            var dbSet = _context.Set<T>().AsQueryable();
            if (exp != null)
                dbSet = dbSet.Where(exp);
            return dbSet;
        }
    }
}
